package com.ocm.tourism.web;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.FileCopyUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.ocm.tourism.core.domain.FileInfo;
import com.ocm.tourism.core.model.ImageItem;
import com.ocm.tourism.core.service.FileInfoService;
import com.ocm.tourism.core.user.BusinessServiceClient;
import com.ocm.tourism.web.util.FileInfoUtil;
import com.ocm.tourism.web.validator.FileValidator;

@SessionAttributes("sessionFileInfoController")
@RequestMapping("/fileInfo")
@Controller
public class FileInfoController {

   private final static String SESSION_ERROROBJECTS="sessionFileInfoController"; 

   @Autowired
   FileInfoService fileInfoService;

   @Autowired
   FileValidator fileValidator;

   @Autowired
   BusinessServiceClient businessServiceClient;

   @RequestMapping(value = "/view/{fileId}", method=RequestMethod.GET)
   public void getFile(@PathVariable("fileId") long fileId, Model uiModel, HttpServletRequest httpServletRequest, HttpServletResponse response) throws IOException {
      FileInfo fileInfo = fileInfoService.find(fileId);
      String uploadDir = httpServletRequest.getSession().getServletContext().getInitParameter("uploadDir");
      File file = new File(uploadDir + fileInfo.getAbsolutePath() + "/" + fileInfo.getName() + "_small");
      FileInputStream fileInputStream = new FileInputStream(file);
      response.setContentType(fileInfo.getMimetypes());
      
      response.setContentLength((int)FileInfoUtil.getSmallLength(fileInfo));
      response.setHeader("Content-Disposition","attachment; filename=\"" + fileInfo.getOriginalfileName() +"\"");
      FileCopyUtils.copy(fileInputStream, response.getOutputStream());
   }
   
   @RequestMapping(value = "/view/{fileId}/medium", method=RequestMethod.GET)
   public void getMediumFile(@PathVariable("fileId") long fileId, Model uiModel, HttpServletRequest httpServletRequest, HttpServletResponse response) throws IOException {
      FileInfo fileInfo = fileInfoService.find(fileId);
      String uploadDir = httpServletRequest.getSession().getServletContext().getInitParameter("uploadDir");
      File file = new File(uploadDir + fileInfo.getAbsolutePath() + "/" + fileInfo.getName() + "_medium");
      FileInputStream fileInputStream = new FileInputStream(file);
      response.setContentType(fileInfo.getMimetypes());
      
      response.setContentLength((int)FileInfoUtil.getMediumLength(fileInfo));
      response.setHeader("Content-Disposition","attachment; filename=\"" + fileInfo.getOriginalfileName() +"\"");
      FileCopyUtils.copy(fileInputStream, response.getOutputStream());
   }
   
   @RequestMapping(value = "/list/{businessId}", method=RequestMethod.GET)
   public String listFiles(@PathVariable("businessId") long businessId, Model uiModel) {
      List<ImageItem> imageItems = this.fileInfoService.retrieveFiles(businessId);
      uiModel.addAttribute("imageItems", imageItems);
      return "fileInfo/view/list";
   }

   @RequestMapping(value = "/intros", method=RequestMethod.GET)
   public String listFiles(Model uiModel) {
      List<ImageItem> imageItems = this.fileInfoService.retrieveMainPicture();
      uiModel.addAttribute("imageItems", imageItems);
      return "fileInfo/view/list";
   }

   @RequestMapping(value = "/business/{businessId}/{businessType}", method=RequestMethod.GET)
   public String listFiles(@PathVariable("businessId") long businessId,@PathVariable("businessType")String businessType, Model uiModel) {
      this.businessServiceClient.validatedAcceptBusiness(businessId);
      List<ImageItem> imageItems = this.fileInfoService.retrieveFiles(businessId);
      uiModel.addAttribute("imageItems", imageItems);
      return "fileInfo/list";
   }

   @RequestMapping(value = "/business/{businessId}/{businessType}/create", method=RequestMethod.GET)
   public String viewUploadFile(@PathVariable("businessId") long businessId,@PathVariable("businessType")String businessType, 
         Model uiModel, SessionStatus sessionStatus) {
      if (uiModel.containsAttribute(SESSION_ERROROBJECTS) && uiModel.asMap().get(SESSION_ERROROBJECTS) != null){
         Model ssUIModel = (Model) uiModel.asMap().get(SESSION_ERROROBJECTS);
         uiModel.addAllAttributes(ssUIModel.asMap());
         sessionStatus.setComplete();
      }
      ImageItem imageItem = new ImageItem();
      uiModel.addAttribute("fileInfo", imageItem);
      return "fileInfo/upload";
   }

   @RequestMapping(value="/upload/{businessId}/{businessType}", method = RequestMethod.POST)
   public String upload(@PathVariable("businessId") long businessId,@PathVariable("businessType") String businessType, 
         ImageItem fileInfo, @RequestParam("fileData")CommonsMultipartFile commonsMultipartFile, 
         BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest, SessionStatus sessionStatus) throws Exception {
      this.businessServiceClient.validatedAcceptBusiness(businessId);
      fileValidator.validate(commonsMultipartFile, bindingResult);
      if (bindingResult.hasErrors()) {
         uiModel.addAttribute(SESSION_ERROROBJECTS, uiModel);
         return "redirect:/"+businessType+"/" + businessId + "/file/create";
      }
      sessionStatus.setComplete();
      ImageItem imageItem = FileInfoUtil.convertImageItem(commonsMultipartFile);
      fileInfoService.uploadFile(businessId, imageItem);
      return "redirect:/"+businessType+"/" + businessId + "/files";
   }
}
